﻿// Copyright 2009 John Diss (www.newgrove.com)
/*
 * This license governs use of the accompanying software. If you use the software, you
 * accept this license. If you do not accept the license, do not use the software.
 * 
 * 1. Definitions
 * The terms "reproduce," "reproduction," "derivative works," and "distribution" have the
 * same meaning here as under U.S. copyright law.
 * A "contribution" is the original software, or any additions or changes to the software.
 * A "contributor" is any person that distributes its contribution under this license.
 * "Licensed patents" are a contributor's patent claims that read directly on its contribution.
 * 
 * 2. Grant of Rights
 * (A) Copyright Grant- Subject to the terms of this license, including the license conditions 
 *     and limitations in section 3, each contributor grants you a non-exclusive, worldwide, 
 *     royalty-free copyright license to reproduce its contribution, prepare derivative works 
 *     of its contribution, and distribute its contribution or any derivative works that you create.
 * (B) Patent Grant- Subject to the terms of this license, including the license conditions and 
 *     limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free 
 *     license under its licensed patents to make, have made, use, sell, offer for sale, import, 
 *     and/or otherwise dispose of its contribution in the software or derivative works of the 
 *     contribution in the software.
 * 
 * 3. Conditions and Limitations
 * (A) No Trademark License- This license does not grant you rights to use any contributors' 
 *     name, logo, or trademarks.
 * (B) If you bring a patent claim against any contributor over patents that you claim are 
 *     infringed by the software, your patent license from such contributor to the software 
 *     ends automatically.
 * (C) If you distribute any portion of the software, you must retain all copyright, patent, 
 *     trademark, and attribution notices that are present in the software.
 * (D) If you distribute any portion of the software in source code form, you may do so only under 
 *     this license by including a complete copy of this license with your distribution. If you 
 *     distribute any portion of the software in compiled or object code form, you may only do so 
 *     under a license that complies with this license.
 * (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no 
 *     express warranties, guarantees or conditions. You may have additional consumer rights under 
 *     your local laws which this license cannot change. To the extent permitted under your local laws, 
 *     the contributors exclude the implied warranties of merchantability, fitness for a particular 
 *     purpose and non-infringement.
 * 
 */
using System;

namespace NPack.Numeric
{
    internal static class NumericOperations<TLeft, TRight, TResult, TOwner>
    {
        public static readonly Func<TLeft, TRight, TResult> Add;
        public static readonly Func<TLeft, TRight, TResult> Div;
        public static readonly Func<TLeft, TRight, TResult> Mul;
        public static readonly Func<TLeft, TRight, TResult> Sub;


        public static readonly Func<TResult, TResult> Abs;
        public static readonly Func<TResult, TResult> Sqrt;
        public static readonly Func<TResult, TResult> Exp;
        public static readonly Func<TResult, TResult> Log;
        public static readonly Func<TResult, Double, TResult> Log2;
        public static readonly Func<TLeft, Double, TResult> Power;
   

        public static readonly Func<Decimal, TResult> FromDecimal;
        public static readonly Func<Double, TResult> FromDouble;
        public static readonly Func<Int32, TResult> FromInt32;
        public static readonly Func<Int16, TResult> FromInt16;
        public static readonly Func<Int64, TResult> FromInt64;
        public static readonly Func<Single, TResult> FromSingle;


        public static readonly Func<TResult, Decimal> ToDecimal;
        public static readonly Func<TResult, Double> ToDouble;
        public static readonly Func<TResult, Int32> ToInt32;
        public static readonly Func<TResult, Int16> ToInt16;
        public static readonly Func<TResult, Int64> ToInt64;
        public static readonly Func<TResult, Single> ToSingle;
        
        

        static NumericOperations()
        {
            Add = MethodLookup.Lookup<TLeft, TRight, TResult, TOwner>(Operator.Add);
            Sub = MethodLookup.Lookup<TLeft, TRight, TResult, TOwner>(Operator.Subtract);
            Mul = MethodLookup.Lookup<TLeft, TRight, TResult, TOwner>(Operator.Multiply);
            Div = MethodLookup.Lookup<TLeft, TRight, TResult, TOwner>(Operator.Divide);
            FromDecimal = (Func<Decimal, TResult>)MethodLookup.Lookup<Decimal, TResult>(Operator.FromDecimal);
            FromDouble = (Func<Double, TResult>)MethodLookup.Lookup<Double, TResult>(Operator.FromDouble);
            FromInt16 = (Func<Int16, TResult>)MethodLookup.Lookup<Int16, TResult>(Operator.FromInt16);
            FromInt32 = (Func<Int32, TResult>)MethodLookup.Lookup<Int32, TResult>(Operator.FromInt32);
            FromInt64 = (Func<Int64, TResult>)MethodLookup.Lookup<Int64, TResult>(Operator.FromInt64);
            FromSingle = (Func<Single, TResult>)MethodLookup.Lookup<Single, TResult>(Operator.FromSingle);

            ToDecimal = (Func<TResult, Decimal>)MethodLookup.Lookup<TResult, Decimal>(Operator.ToDecimal);
            ToDouble = (Func<TResult, Double>)MethodLookup.Lookup<TResult, Double>(Operator.ToDouble);
            ToInt16 = (Func<TResult, Int16>)MethodLookup.Lookup<TResult, Int16>(Operator.ToInt16);
            ToInt32 = (Func<TResult, Int32>)MethodLookup.Lookup<TResult, Int32>(Operator.ToInt32);
            ToInt64 = (Func<TResult, Int64>)MethodLookup.Lookup<TResult, Int64>(Operator.ToInt64);
            ToSingle = (Func<TResult, Single>)MethodLookup.Lookup<TResult, Single>(Operator.ToSingle);

            Abs = (Func<TResult, TResult>)MethodLookup.Lookup<TResult, TResult>(Operator.Abs);
            Sqrt = (Func<TResult, TResult>)MethodLookup.Lookup<TResult, TResult>(Operator.Sqrt);
            Power = (Func<TLeft, Double, TResult>) MethodLookup.Lookup<TResult, Double>(Operator.Pow);
            Exp = (Func<TResult, TResult>) MethodLookup.Lookup<TResult, TResult>(Operator.Exp);
            Log = (Func<TResult, TResult>)MethodLookup.Lookup<TResult, TResult>(Operator.Log);
            Log2 = (Func<TResult, Double, TResult>)MethodLookup.Lookup<TResult, TResult>(Operator.Log2);
        }

    }
}